/**********************************************************************************
 * Code license:  GNU General Public License v3                                   *
 * Main page:     https://code.google.com/p/library-cross-platform/               *
 * Issue tracker: https://code.google.com/p/library-cross-platform/issues/list    *
***********************************************************************************/

package library.compiler;

import java.io.*;
import java.util.*;
import library.util.*;
import library.parser.*;
import library.file.*;

@SuppressWarnings({"rawtypes", "unchecked"})
public class InclFileListBuild  extends EventListenerExt {

  protected              DirectoryList    directoryList;
  protected              List             projectFileList         = new ArrayList();
  protected              int              nextCheckedFileIndex    = 0;
  protected              java.lang.String mainFunctionFile;
  protected              java.lang.String file2Parse;
  protected static final java.lang.String main_h_except           = new java.lang.String("main.h");
  protected static final java.lang.String main_s_except           = new java.lang.String("main.s");

  protected static final StringBuilder    keyWordInclude          = new StringBuilder("#include");


  public InclFileListBuild() {
  }
  
  public void setDirectoryList(DirectoryList dl) {
    directoryList = dl;
  }
  
  public DirectoryList getDirectoryList() {
    return directoryList;
  }

  public void setMainFunctionFile(java.lang.String file) {
    mainFunctionFile = file;
    addFile(mainFunctionFile);
  }
  
  public void addFile(java.lang.String file) {
    if(file.endsWith(".h")) {
      java.lang.String newFile = file.replace(".h", ".s");
      if(projectFileList.indexOf(newFile) == -1)
        projectFileList.add(newFile);
    } else if(file.endsWith(".s") && !file.equalsIgnoreCase(main_s_except)) {
      java.lang.String newFile = file.replace(".s", ".h");
      if(projectFileList.indexOf(newFile) == -1)
        projectFileList.add(newFile);
    } else if(file.equalsIgnoreCase(main_s_except)) {
      if(projectFileList.indexOf(file) == -1)
        projectFileList.add(file);
    }
  }
  
  protected void removeFile(java.lang.String file) {
    int index = projectFileList.indexOf(file);
    if(index != -1)
      projectFileList.remove(index);
  }
  
  public List getProjectFileList() {
    return projectFileList;
  }
 
  public int skipEmptyData(StringBuilder raw_data, int index) {
    if(index >= raw_data.length())
     return index;
    /* skip ' ' and '\t' */
    while(raw_data.charAt(index) != '\r'    &&
          raw_data.charAt(index) != '\n'    &&
          raw_data.charAt(index) != '\0'    &&
          (raw_data.charAt(index) == ' ' || raw_data.charAt(index) == '\t'))
    {
      index ++;
    }
    return index;
  }

  public int skipEmptyData(java.lang.String raw_data, int index) {
    if(index >= raw_data.length())
     return index;
    /* skip ' ' and '\t' */
    while(raw_data.charAt(index) != '\r'    &&
          raw_data.charAt(index) != '\n'    &&
          raw_data.charAt(index) != '\0'    &&
          (raw_data.charAt(index) == ' ' || raw_data.charAt(index) == '\t'))
    {
      index ++;
    }
    return index;
  }

  StringBuilder removeQuotes(final StringBuilder str) {
    int length = str.length();
    int index = 0;
    StringBuilder result = new StringBuilder(); 
    while(index < length) {
      if(str.charAt(index) != '"')
       result.append(str.charAt(index));
      index ++;
    }
    return result;
  }
  protected void parse4Include() throws FileNotFoundException{
    AdoptedAsciiReader        reader           = null;
    java.lang.String          readLine         = null;
    java.lang.String          isPresentresult  = null;
    java.lang.StringBuilder   data             = new java.lang.StringBuilder();
    java.lang.StringBuilder   indata           = new java.lang.StringBuilder();
    AsciiParser               strParser        = new AsciiParser();
    StringParamValue          paramValue;

      
    isPresentresult = getDirectoryList().isPresentFile(file2Parse);
    if(isPresentresult == null && !file2Parse.equals(main_h_except)) {
      throw new FileNotFoundException("**** The file: " + file2Parse + " is not found");
    } else if(isPresentresult == null && file2Parse.equals(main_h_except)) {
      return;
    } else
      file2Parse = isPresentresult;
      
    reader = new AdoptedAsciiReader(new File(file2Parse));
      
    try {
      while((readLine = reader.readLine()) != null) {
        if(readLine.length() > 0) {
         indata.setLength(0);
         indata.append(readLine);
         strParser.remove_space(indata);
         data.setLength(0);
         paramValue = strParser.parseDataParameter(indata, 0, '"');
         if(strParser.compareStrings(paramValue.name, keyWordInclude) == true) {
           paramValue.value = removeQuotes(paramValue.value);
           addFile(paramValue.value.toString());
         }
        }
      }
    } catch(IOException e) {
      e.printStackTrace();
    }
  }

  public boolean start() throws IllegalEventException {
//    System.out.println("InclFileListBuild.EventStart.parse(...)");
    
    file2Parse = (java.lang.String)projectFileList.get(nextCheckedFileIndex ++);
    try {
      parse4Include();
    } catch (FileNotFoundException ex) {
     System.err.println(ex.getMessage());
     parent.setNextEvent(CompilerEventList.COMPILER_EVENT_FILE_NOT_FOUND);
     return false;
    }
      
    if(projectFileList.size() > nextCheckedFileIndex)
      parent.setNextEvent(CompilerEventList.COMPILER_EVENT_SEARCH_INCLUDE);
    else
      parent.setNextEvent(CompilerEventList.COMPILER_EVENT_SEARCH_INCLUDE_COMPLETE);
    return false;
  }
}

